#============================================
# 单表操作
# # django自带的sqlite3数据库对日期格式不是很敏感处理的时候容易出错
# 测试脚本
# 当你只是想测试dj ango中的某一个py文件内容 那么你可以不用书写前后端交互的形式
# 而是直接写一个测试脚本即可

#测试环境的准备 去manage . py中拷 贝前四行代码 然后自己写两行
# import os
# import sys
# if  __name__ =  __main__ " :
    # os . environ. setdefault ("DJANGO_ SETTINGS_ MODULE", " day64. settings")
    # import django
    # django.setup()
# #在这个代码块的下面就可以测试django里面的单个py文件了
#============================================
# 查看内部sq|语句的方式
# #方式1
# res = models.User .objects.values_ list('name','age') # <QuerySet
# [('jason', 18)， ( 'egonPPP', 84)]>
# pr int (res. query)

# queryset对象才能够点击query查看内部的sq1语句
#方式2:所有的sq1语句都能查看
#去配置文件中配置一下即可
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}
#============================================
# res = models.User.objects.filter(pk=2).delete()
# print(res)
# pk会自动查找到当前表的主键字段指代的就是当前表的主键字段
# 用了pk之后你就不需要指代当前表的主键字段到底叫什么了
# uid
# pid
# sid
# user_obj = modeLs.User.objects.filter(pk=1).first()
# user_obi.delete()

# 必知必会13条
# 1.all()      查询所有数据

# 2.filter()   带有过滤条件的查询

# 3.get()      直接拿数据对象但是条件不存在直接报错

# 4. first()    拿queryset里面第一个元素
# res = models.User.objects.all().first()
# print(res)

# 5.Last()      拿queryset里面最后一个元素
# res = models.User.objects.all().Last()
# print(res)

# 6.values() 可以指定获取的数据字段    seLect name,age from ...
# res = models.user.objects.values('name','age')  结果为列表套字典
#  # <QuerySet [{'jason', 18}，{'egonPPP', 84}]>
# print(res)

# 7.vaLues_list()
# res = modeLs.User.objects.values_list('name','age')  结果为列表套元组 
#  # <QuerySet [('jason', 18)，('egonPPP', 84)]>
# print(res)

# 8.distinct()
# 去重
# res = models .User. objects . values('name' 'age ').distinct() 
# print(res) 
# 去重一定要是一模一样的数据
# 如果带有主键那么肯定不一样你在往后的查询中定不要忽略主键

# 9.order_by()
# res = modeLs .User. objects. order_ by('age')
#默认升序
# res = models . User . objects . order_ by('-age' )
#降序

# 10.reverse() 反转的前提是 数据已经排过序了order_ by()
#res = models. User . objects.all()
# res1 = modeLs.User . objects. order_ by( ' age' ) . reverse()
# print(res ,res1)

# 11. count()
# 统计当前数据的个数
# res = models . User . objects . count()
# print(res)

# 12.exclude() 排除在外
# res = models.User. objects。exclude (name= 'jason')
# print(res)

# 13.exists () 判断数据是否存在
# 基本用不到
# res = models. User . objects. filter(pk=4} . exists()
# print(res)
#============================================
#神奇的双下划线查询
# 1年龄大于35岁的数据
# res = models . User. objects . filter(age__gt=35)
# print(res)
# 2年龄小于35岁的数据
# res = modeLs . User. objects . filter(age__lt=35)
# print(res)
#大于等于 小于等于
# res = models . User . objects. filter(age__gte=35)
# print(res)
# res = models . User . objects. filter(age__lte=35)
# print(res)

#年龄是18或者32或者40
# res = modeLs. User .objects . filter(age__ in= [18,32, 40])
# print(res)

#年龄在18到40岁之间的首尾都要
#res = models.User .objerts . filter(age __range=[18, 40])
# print(res)

#查询出名字里面含有s的数据模糊查询
# res = models. User。objects. filter(name__contains='s') 
# print(res)
#是否区分大小写查询出名字里面含 有p的数据区分大小写 
# res = modeLs . User.objects.filter(name__contains='p')
# print(res)
# 忽略大小写
# res = modeLs . User.objects.filter(name__icontains='p')
# print(res)

# res = models . User . objects . filter(name__ startswith= 'j')以..开头
# res1 = models . User . objects . filter (name__ endswith= 'j')以..结尾
# print(res,res1)

 #查询出注册时间是2020 1月
# res = models.User . objects. filter( time__ month='1' )
# res = models.User.objects. filter( time__ year='2020' )
#============================================
# 多表操作
 #一对多外键增删改查
#增
# 1直接写实际字段id
# models.Book.objects.create(titLe='三国演义',price=123.23, pubLish_ id=1)
#2虚拟字段对象
# publish_ obj = modeLs 。PubLish. objects。filter(pk=2) .first()
# models . Book. objects . create(title=红楼梦' 1 price=666.23 , pubLish=pubLish_ obj)

#修改
# modeLs . Book . objects . filter(pk=1) . update(pubLish_id=2)
# publish_ _obj = models . PubLish . objects. filter(pk=1) . first()
# models . Book. objects . filter(pk=1) . update (pubLish=pubLish_obj)


# 多对多 增删改查 就是在操作第三张表
#如何给书籍添加作者?
# book_ obj = models . Book . objects . filter(pk=1) . first()
# print (book_ obj . authors) # 就类似于你已经到了第三张关系表了
# book_ obj . authors . add(1) # 书籍id为1的书籍绑定个主键为1 的作者
# book_ obj . authors。add(2, 3)

# author_ obj = models . Author . objects . filter(pk=1) . first()
# author_ obj1 = modeLs . Author . objects . filter(pk=2) . first()
# author_ obj2 = modeLs . Author . objects . filter(pk=3). first()
# book_ obj . authors . add(author obj)
# book_ obj . authors . add(author_ obj)
# add给第三张关系表添加数据
# 括号内既可以传数字也可以传对象并且都支持多个

# 删
# book_ obj . authors . remove (2)
# book_ obj 。authors。remove(1,3)
# author_ obj = models . Author . objects. filter(pk=2) . first()
# author_ obj1 = models 。Author。objects . filter(pk=3) .first()
# book_ obj . authors . remove (author_ obj 1 author_ obj1)
# remove
# 括号内既可以传数字也可以传对象并且都支持多个

# 改 
# book_ obj . authors . set([1,2])
#括号内必须给一个可迭代对象
# book_ obj . authors.set([3]) # 括号内必须给一个可迭代对象
# author_ obj = models 。Author . objects . filter (pk=2) . first()
# author obj1 = modeLs . Author . objects . filter(pk=3) . first()
# book_ obj . authors . set( [ author_ _obj , author_ obj1]) # 括号内必须给一个可迭代对象
# set
# 括号内必须传一个可迭代对象， 该对象内既可以数字也可以对象并且都支持多个|

# 共清空
# #在第三张关系表中清空某个书籍与作者的绑定关系
# book_ obj . authors . cLear()
# cLear
# 括号内不要加任何参数

# 总结
# 一对多就是正常的先定为到一个对象，创建就可以了
# 多对多就是先定位到一个多对多的对象再去点对应的外键，然后进行增删改add,remove,set,
# 注意set里面必须为可迭代对象,
# 注意这里操作的数值，可以为对象（会自动匹配主键id）
#============================================
# 正反向的概念
# #正向
# #反向
# 外键字段在我手上那么，我查你就是正向
# 外键字段如果不在手上，我查你就是反向
# book >> >外键字段在书那儿(正向)>>> publish
# publish >>> 外键字段在书那儿(反向)>>>book
# 一对一和多对多正反向的判断也是如此

# 1. 查询书籍主键为1的出版社
# book_ obj =models.Book . objects. filter(pk=1). first()
# #书查出版社正向
# res = book_ obj.pubLish
# print(res)
# print(res. name)
# print(res. addr)

# # 2. 查询书籍主键为2的作者
# book_ obj = modeLs . Book . objects . filter(pk=2). first()
# #书查作者正向
# # res = book_ obj. authors # app01。Author. None
# res = book_ obj . authors.all() # app01。Author . None
# print(res)

# 3.查询作者jason的电话号码
# author_ obj = modeLs 。Author。objects。filter(name= 'jason' ) .first()
# res = author obj . author_ detail
# print(res)
# print(res . phone)
# print(res。addr)
# 在书写orm语句的时候跟写sq1语句-样的
# 不要企图一次性将orm语句写完如果比较复杂就写一点看-点
# 正向什么时候需要加.all()
# 当你的结果可能有多个的时候就需要加.all()
# 如果是个则直接拿到数据对象

# # 4.查询出版社是东方出版社出版的书
# publish_ obj = modeLs . Publish . objects . filter(name= '东方出版社' ) . first()
# #出版社查书反向
# # res = pubLish_ obj.book_ set
# # app01. Book. None
# res = pubLish_ obj . book_ set . all()
# print(res)


# 5.查询作者是jason写过的书
# author_ obj = models . Author . objects . filter(name= ' jason'). first()
#作者查书
# 反向
# res = author_ obj.book_ set
# app01. Book. None
# res = author_ obj . book_ set.all()
# print(res)

# 6.查询手机号是110的作者姓名
# author_ detail_ obj = models . AuthorDetail. objects . filter(phone=110) . first()
# res = author_ detail_ obj . author
# print (res . name)
# 基于对象
# 反向查询的时候
# 当你的查询结果可以有多个的时候就必须加_set.all()
# 当你的结果只有一个的时候不需要加_set.all()
# 自己总结出自己方便记忆的即可每个人都可以不一样
#============================================
# 给予双下划线的跨表查询
# 1、查询iason的手机号
# res = models . Author . objects . filter(name= 'jason' ) . values(' author_detail__phone ' )
# print(res)

# 2查询书籍志键为1的出版社名称和书的名称
# res = modeLs . Book . objects . filter(pk=1) . values('titLe', 'pubLish__name' )
# print(res)

# 3.查询书籍主键为1的作者姓名
# res = modeLs . Book . objects. filter(pk=1) . values( ' authors__ name' )
# print(res)

 
# 扶查询书籍击键是1的作者的手机景
# # book author authordetail
#============================================











